home *** CD-ROM | disk | FTP | other *** search
- #include "windows.h"
- #include "4d.h"
-
- /*
- (C) Copyright Microsoft Corp. 1991. All rights reserved.
-
- You have a royalty-free right to use, modify, reproduce and
- distribute the Sample Files (and/or any modified version) in
- any way you find useful, provided that you agree that
- Microsoft has no warranty obligations or liability for any
- Sample Application Files which are modified.
- */
-
- extern int atoi(char *);
-
- #define X 0
- #define Y 1
- #define Z 2
- #define W 3
-
-
- MATRIXFX Matrix4D (FIXED4D m11,FIXED4D m12,FIXED4D m13,FIXED4D m14,
- FIXED4D m21,FIXED4D m22,FIXED4D m23,FIXED4D m24,
- FIXED4D m31,FIXED4D m32,FIXED4D m33,FIXED4D m34,
- FIXED4D m41,FIXED4D m42,FIXED4D m43,FIXED4D m44);
-
-
- /* Exports */
- POINTFX4D Origin = {0,0,0,FX(1)};
- FIXED4D epsilon = MAKEFX(0,1); /* 0.0001; */
-
- POINTFX4D CreatePoint4D(x,y,z,w)
- FIXED4D x,y,z,w;
- {
- POINTFX4D NewPoint;
- NewPoint.x = x;
- NewPoint.y = y;
- NewPoint.z = z;
- NewPoint.w = w;
- return NewPoint;
- }
-
- MATRIXFX Matrix4D (FIXED4D m11,FIXED4D m12,FIXED4D m13,FIXED4D m14,
- FIXED4D m21,FIXED4D m22,FIXED4D m23,FIXED4D m24,
- FIXED4D m31,FIXED4D m32,FIXED4D m33,FIXED4D m34,
- FIXED4D m41,FIXED4D m42,FIXED4D m43,FIXED4D m44)
-
- {
- MATRIXFX M;
-
- M.T[0][0] = m11; M.T[0][1] = m12; M.T[0][2] = m13; M.T[0][3] = m14;
- M.T[1][0] = m21; M.T[1][1] = m22; M.T[1][2] = m23; M.T[1][3] = m24;
- M.T[2][0] = m31; M.T[2][1] = m32; M.T[2][2] = m33; M.T[2][3] = m34;
- M.T[3][0] = m41; M.T[3][1] = m42; M.T[3][2] = m43; M.T[3][3] = m44;
-
- return M;
- }
-
-
- /*
- ** Return the point 1 t-th along the way
- ** from P0 to P1.
- */
- extern POINTFX4D Ratio4D(P0,P1,t)
- POINTFX4D P0,P1;
- FIXED4D t;
- {
- POINTFX4D P;
-
- P.x = P0.x + FXMUL(t,(P1.x - P0.x));
- P.y = P0.y + FXMUL(t,(P1.y - P0.y));
- P.z = P0.z + FXMUL(t,(P1.z - P0.z));
- P.w = ONE;
-
- return P;
- }
-
- POINTFX4D PxT4D(P,T)
- POINTFX4D P;
- MATRIXFX *T;
- {
- POINTFX4D Q;
- int i,k;
- FIXED4D Qi;
-
- #ifdef HOMO
- for (i = 0; i < 4; i++)
- {
- Qi = ZERO;
- for (k = 0; k < 4; k++)
- Qi += FXMUL(P.P[k],(T->T[i][k]));
- Q.P[i] = Qi;
- }
- #else
- Q.x = T->T[0][3] + FXMUL(P.x,T->T[0][0]) + FXMUL(P.y,T->T[0][1]) + FXMUL(P.z,T->T[0][2]);
- Q.y = T->T[1][3] + FXMUL(P.x,T->T[1][0]) + FXMUL(P.y,T->T[1][1]) + FXMUL(P.z,T->T[1][2]);
- Q.z = T->T[2][3] + FXMUL(P.x,T->T[2][0]) + FXMUL(P.y,T->T[2][1]) + FXMUL(P.z,T->T[2][2]);
- #endif
- return Q;
- }
-
- void TransformPoints(pT,pP,pD,cnt)
- MATRIXFX *pT;
- POINTFX4D FAR *pP;
- POINTFX4D FAR *pD;
- int cnt;
- {
- FIXED4D x,y,z,w;
-
- while (cnt-- > 0)
- {
- x = pP->x;
- y = pP->y;
- z = pP->z;
- w = pP->w;
-
- if (w == ZERO)
- {
- pD->x = FXMUL(x,pT->T[0][0]) + FXMUL(y,pT->T[0][1]) + FXMUL(z,pT->T[0][2]);
- pD->y = FXMUL(x,pT->T[1][0]) + FXMUL(y,pT->T[1][1]) + FXMUL(z,pT->T[1][2]);
- pD->z = FXMUL(x,pT->T[2][0]) + FXMUL(y,pT->T[2][1]) + FXMUL(z,pT->T[2][2]);
- pD->w = w;
- }
- else
- {
- pD->x = pT->T[0][3] + FXMUL(x,pT->T[0][0]) + FXMUL(y,pT->T[0][1]) + FXMUL(z,pT->T[0][2]);
- pD->y = pT->T[1][3] + FXMUL(x,pT->T[1][0]) + FXMUL(y,pT->T[1][1]) + FXMUL(z,pT->T[1][2]);
- pD->z = pT->T[2][3] + FXMUL(x,pT->T[2][0]) + FXMUL(y,pT->T[2][1]) + FXMUL(z,pT->T[2][2]);
- pD->w = w;
- }
-
- pP++;
- pD++;
- }
- }
-
-
- MATRIXFX Transpose4D(T)
- MATRIXFX *T;
- {
- MATRIXFX Tt;
- int i,j;
-
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) {
- Tt.T[i][j] = T->T[j][i];
- }
- }
- return Tt;
- }
-
- MATRIXFX TxT4D(A, B)
- MATRIXFX *A, *B;
- {
- MATRIXFX C;
- int i,j,k;
- FIXED4D Cij;
-
- for (j = 0; j < 4; j++)
- for (i = 0; i < 4; i++)
- {
- Cij = ZERO;
- for (k = 0; k < 4; k++)
- Cij += FXMUL(A->T[k][j],B->T[i][k]);
- C.T[i][j] = Cij;
- }
- return C;
- }
-
- MATRIXFX Identity4D()
- {
- MATRIXFX I;
- int i,j;
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- I.T[i][j] = FX(i == j);
- return I;
- }
-
- MATRIXFX Translate4D(V)
- VECTORFX V;
- {
- MATRIXFX T;
-
- T = Identity4D();
- T.T[0][3] = V.x;
- T.T[1][3] = V.y;
- T.T[2][3] = V.z;
- return T;
- }
-
- MATRIXFX UniformScale4D(s)
- FIXED4D s;
- {
- return Scale4D(CreatePoint4D(s,s,s,ONE));
- }
-
- MATRIXFX Scale4D(P)
- POINTFX4D P;
- {
- MATRIXFX T;
-
- T = Identity4D();
- T.T[0][0] = P.x;
- T.T[1][1] = P.y;
- T.T[2][2] = P.z;
- T.T[3][3] = P.w;
- return T;
- }
-
- /******************************************************************************
- returns a Matrix to rotate about the z axis
- ******************************************************************************/
- MATRIXFX RotateZ (deg)
- FIXED4D deg;
- {
- return Matrix4D( fxcos(deg), -fxsin(deg), ZERO, ZERO,
- fxsin(deg), fxcos(deg), ZERO, ZERO,
- ZERO, ZERO, ONE, ZERO,
- ZERO, ZERO, ZERO, ONE);
- }
-
-
- /******************************************************************************
- returns a Matrix to rotate about the y axis
- ******************************************************************************/
- MATRIXFX RotateY (deg)
- FIXED4D deg;
- {
- return Matrix4D( fxcos(deg), ZERO, -fxsin(deg), ZERO,
- ZERO, ONE, ZERO, ZERO,
- fxsin(deg), ZERO, fxcos(deg), ZERO,
- ZERO, ZERO, ZERO, ONE);
- }
-
-
- /******************************************************************************
- returns a Matrix to rotate about the x axis
- ******************************************************************************/
- MATRIXFX RotateX (deg)
- FIXED4D deg;
- {
- return Matrix4D( ONE, ZERO, ZERO, ZERO,
- ZERO, fxcos(deg), -fxsin(deg), ZERO,
- ZERO, fxsin(deg), fxcos(deg), ZERO,
- ZERO, ZERO, ZERO, ONE);
- }
-
- MATRIXFX Perspective4D(f)
- FIXED4D f;
- {
- MATRIXFX P;
-
- P = Identity4D();
- if ((f < epsilon) && (f > (-epsilon)))
- {
- /* fprintf(stderr,"Perspective4D: f (%d.%d) is too small.\n",f); */
- if (f < ZERO) f = (-epsilon);
- else f = epsilon;
- }
- P.T[2][2] = FXDIV(ONE,f); P.T[3][2] = FXDIV(ONE,f);
- P.T[2][3] = -ONE; P.T[3][3] = ZERO;
- return P;
- }
- #if 0
- void PrintFx(fx)
- FIXED4D fx;
- {
- WORD f;
- int i;
-
- if (fx < 0)
- {
- fx = -fx;
- i = -FXINT(fx);
- f = FXDFRAC(fx);
- }
- else
- {
- i = FXINT(fx);
- f = FXDFRAC(fx);
- }
- WinPrintf("%5d.%04u ",i,f);
- }
- #endif
-
- FIXED4D atofx(sz)
- char *sz;
- {
- int i;
- WORD f;
- FIXED4D fx;
- BOOL fminus = FALSE;
- int d;
-
- if (*sz == '-')
- {
- fminus = TRUE;
- sz++;
- }
-
- i = atoi(sz);
-
- while (*sz && *sz != '.')
- sz++;
-
- if (*sz)
- f = atoi(++sz);
- else
- f = 0;
-
- if (f < 10)
- d = 10;
- else if (f < 100)
- d = 100;
- else if (f < 1000)
- d = 1000;
- else if (f < 10000)
- d = 10000;
-
- f = (WORD)((DWORD)f * 65536L / d);
-
- fx = MAKEFIXED4D(i,f);
-
- if (fminus)
- {
- fx = -fx;
- }
- return fx;
- }
-
- #if 0
- void PrintMatrix(T)
- MATRIXFX *T;
- {
- int i,j;
-
- for (i=0; i<4; i++)
- {
- WinPrintf("|");
- for (j=0; j<4; j++) {
- WinPrintf(" ");
- PrintFx(T->T[j][i]);
- WinPrintf(" ");
- }
- WinPrintf("|\n");
- }
- }
-
- void PrintPoint(P)
- POINTFX4D P;
- {
- WinPrintf("(");
- PrintFx(P.x); WinPrintf(" ");
- PrintFx(P.y); WinPrintf(" ");
- PrintFx(P.z); WinPrintf(" ");
- PrintFx(P.w); WinPrintf(")");
- }
- #endif
-
- /*
- ** Vectors are represented as 4-tuples with the last component
- ** being 0. This representation allows them to be correctly transformed
- ** by homogeneous matrices.
- */
- VECTORFX CreateVector4D(a,b,c)
- FIXED4D a,b,c;
- {
- VECTORFX NewVector;
-
- NewVector.x = a;
- NewVector.y = b;
- NewVector.z = c;
- NewVector.w = ZERO;
- return NewVector;
- }
-
- #if 0
- void PrintVector(V)
- VECTORFX V;
- {
- WinPrintf("[");
- PrintFx(V.x); WinPrintf(" ");
- PrintFx(V.y); WinPrintf(" ");
- PrintFx(V.z); WinPrintf(" ");
- PrintFx(V.w); WinPrintf("]");
- }
- #endif
-
- VECTORFX VxT4D(V,T)
- VECTORFX V;
- MATRIXFX *T;
- {
- VECTORFX Q;
-
- Q.x = FXMUL(V.x,T->T[0][0]) + FXMUL(V.y,T->T[0][1]) + FXMUL(V.z,T->T[0][2]);
- Q.y = FXMUL(V.x,T->T[1][0]) + FXMUL(V.y,T->T[1][1]) + FXMUL(V.z,T->T[1][2]);
- Q.z = FXMUL(V.x,T->T[2][0]) + FXMUL(V.y,T->T[2][1]) + FXMUL(V.z,T->T[2][2]);
- return Q;
- }
-
- VECTORFX Cross4D(v1, v2)
- VECTORFX v1, v2;
- {
- VECTORFX v;
-
- #if 1
- fxCross4D(&v,v1,v2);
- #else
- v.x = FXMUL(v1.y,v2.z) - FXMUL(v1.z,v2.y);
- v.y = -(FXMUL(v1.x,v2.z) - FXMUL(v1.z,v2.x));
- v.z = FXMUL(v1.x,v2.y) - FXMUL(v1.y,v2.x);
- v.w = ZERO;
- #endif
-
- return v;
- }
-
- FIXED4D Dot4D(v1,v2)
- VECTORFX v1, v2;
- {
- #if 0
- if (v1.x < 0)
- v1.x = - v1.x;
- if (v1.y < 0)
- v1.y = - v1.y;
- if (v1.z < 0)
- v1.z = - v1.z;
- #endif
-
- return FXMUL(v1.x,v2.x) + FXMUL(v1.y,v2.y) + FXMUL(v1.z,v2.z);
- }
-
- FIXED4D Vmag( v)
- VECTORFX v;
- {
- return fxLength3D(v.x,v.y,v.z);
- }
-
- ULONG ulVmag(v)
- VECTORFX v;
- {
- return ulsqrt((ULONG)lDot4D(v,v));
- }
-
- VECTORFX Normalize(v)
- VECTORFX v;
- {
- VECTORFX vout;
- FIXED4D l = Vmag(v);
-
- if (l == 0) {
- return v;
- /* printf("Can't normalize a zero vector.\n"); */
- /* exit(-1); */
- }
-
- vout.x = FXDIV(v.x,l);
- vout.y = FXDIV(v.y,l);
- vout.z = FXDIV(v.z,l);
- vout.w = ZERO;
-
- return vout;
- }
-
- /*
- ** Return the vector V=P1-P0.
- */
- extern VECTORFX Pdiff(P1,P0)
- POINTFX4D P1,P0;
- {
- VECTORFX V;
-
- #ifdef HOMO
- P1.x /= P1.w; P1.y /= P1.w; P1.z /= P1.w;
- P0.x /= P0.w; P0.y /= P0.w; P0.z /= P0.w;
- #endif
-
- V.x = P1.x - P0.x;
- V.y = P1.y - P0.y;
- V.z = P1.z - P0.z;
- V.w = ZERO;
-
- return V;
- }
-
- /*
- ** Return the vector s*V.
- */
- VECTORFX Vscale(s,V)
- FIXED4D s;
- VECTORFX V;
- {
- V.x = FXMUL(V.x,s);
- V.y = FXMUL(V.y,s);
- V.z = FXMUL(V.z,s);
- V.w = ZERO;
-
- return V;
- }
-
- /*
- ** Return the vector V1+V1.
- */
- VECTORFX Vadd(V1, V2)
- VECTORFX V1, V2;
- {
- VECTORFX V;
-
- V.x = V1.x + V2.x;
- V.y = V1.y + V2.y;
- V.z = V1.z + V2.z;
- V.w = ZERO;
-
- return V;
- }
-
- /*
- ** Return the vector V1-V1.
- */
- VECTORFX Vsub(V1, V2)
- VECTORFX V1, V2;
- {
- VECTORFX V;
-
- V.x = V1.x - V2.x;
- V.y = V1.y - V2.y;
- V.z = V1.z - V2.z;
- V.w = ZERO;
-
- return V;
- }
-
- /*
- ** Return the point P+V.
- */
- POINTFX4D PVadd(P,V)
- POINTFX4D P;
- VECTORFX V;
- {
- POINTFX4D p;
-
- p.x = P.x + V.x;
- p.y = P.y + V.y;
- p.z = P.z + V.z;
- p.w = ONE;
-
- return p;
- }
-
- /*
- ** Implementation Module: ray
- ** Purpose: ray manipulation.
- **
- */
-
- RAYFX CreateRay(P0,P1)
- POINTFX4D P0,P1;
- {
- RAYFX R;
-
- R.P0 = P0;
- R.P1 = P1;
- return R;
- }
-
- RAYFX RxT4D(R,T)
- RAYFX R;
- MATRIXFX *T;
- {
- RAYFX NewRay;
-
- NewRay.P0 = PxT4D(R.P0, T);
- NewRay.P1 = PxT4D(R.P1, T);
-
- return NewRay;
- }
-
-